
package com.lee.tree; 
 
import com.lee.database.HBaseConnPool; 
import com.lee.info.CkFlowInfo; 
import com.lee.logger.Logger; 
import com.lee.utils.ArrayUtils; 
import com.lee.utils.Combination; 
import com.lee.utils.ConstantsUtils; 
import com.lee.utils.RulesUtils; 
import org.apache.commons.lang.StringUtils; 
 
import java.io.IOException; 
import java.io.Serializable; 
import java.util.*; 
import java.util.stream.Collectors; 
 
public class FPStreamGenerate implements Serializable { 
    private static final FPStreamGenerate instance = new FPStreamGenerate();
    private PatternTree master;
    FPStreamGenerate(){
        master = new PatternTree();
    }
    public PatternTree init(){
        PatternTree master = new PatternTree();
        return master;
    }
    public PatternTree getMaster(){
        return master;
    }
    public static FPStreamGenerate getInstance(){
        Logger.debug("get FPStreamGenerate instance");
        if(instance == null){
            Logger.error("get instance error, instance is null.");
        }
        return instance;
    }
 
 
    public void generate(PatternTree master,List<TwoTuple<List<String>, Long>> frequentItemsets,long total) throws Exception {
        List<TwoTuple<List<String>, Long>> result = frequentItemsets;
 
        result = result.stream().map(item->{
 
            item.first.sort(String::compareTo);
            return item;
        }).collect(Collectors.toList());
        result.sort(Comparator.comparing(a -> StringUtils.join(a.first, "")));
 
        Logger.info(total,"从patterntree 获取频繁集");
 
        for(TwoTuple<List<String>, Long> resultItem:result){
            List<String> itemset = resultItem.first;
 
 
            long support = resultItem.second;
            master.add(itemset,support);
        }
 
        int masterTotal = master.inspectAndUpdate();
        master.inspect();
 
        List<TwoTuple<List<String>,Long>> frequents = master.getFrequents();
 
        Logger.info(masterTotal,"生成关联规则");
        Map<List<String>,Long> patterns = new HashMap();
        for(TwoTuple<List<String>,Long> frequentItem:frequents){
            List<String>  itemset = frequentItem.first;
            long support = frequentItem.second;
 
 
            List<String> sortItemset = new ArrayList<>(itemset);
            sortItemset.sort(String::compareTo);
 
            patterns.put(sortItemset,support);
        }
 
        generateAssociationRules(patterns,masterTotal);
        Logger.info(masterTotal,"生成关联规则成功");
 
    }
 
 
 
 
 
    public void generateAssociationRules(Map<List<String>,Long> patterns,int masterTotal) throws IOException {
 
        List<List<String>> keys =  new ArrayList(patterns.keySet());
 
        Combination<String> combination = new Combination<>();
        long total = masterTotal * ConstantsUtils.DATA_BLOCK_SIZE;
        for(int idx=0;idx<keys.size();idx++){
            List<String> itemset = keys.get(idx);
            long upperSupport = patterns.get(itemset);
            for(int i=0;i<itemset.size();i++){
                List<List<String>> combinations = combination.combinations(itemset, i);
                for(List<String> antecedent:combinations){
                      antecedent.sort(String::compareTo);
                    List<String> consequent = ArrayUtils.getSubItem(itemset, antecedent);
 
                    if(patterns.containsKey(antecedent) && patterns.containsKey(consequent)){
 
                        long lowerSupport = patterns.get(antecedent);
 
                        double pLowerSupport = 1.0 * lowerSupport / total;
                        double support = 1.0 * upperSupport / total;
                        double confidence = lowerSupport == 0 ? 0 : 1.0 * upperSupport / lowerSupport;
                        if(confidence >= ConstantsUtils.MIN_CONF && support >= ConstantsUtils.MIN_SUPPORT){
 
                            RulesUtils.setValueByKey(upperSupport,antecedent,consequent,confidence,support);
 
                        }
 
                    }
                }
 
                ;
            }
 
        }
 
 
     }
} 
